﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SuperKit
{
    class AutoResize : CommandExecutor {
        private class AutoResizeItem : ThreadToolItem {
            public AutoResize Parent { get; }
            public FileInfo info;
            public bool processed { get; set; } = false;

            public AutoResizeItem(AutoResize parent, FileInfo info) {
                this.Parent = parent;
                this.info = info;
                this.processed = false;
            }

            public override void Process() {
                Parent.Process(info);
            }

            public override string ToString() {
                return info.Name;
            }

            public override string GetStartMessage() {
                return Parent.GetStatus(info.Name);
            }
        }

        private const string RESIZE_DIR = "(RESIZE)";
        // 是否覆盖原文件，如果这个为False，则会在项目下面新建一个(RESIZE)的文件夹来保存文件
        public bool isOverride = false;
        public bool zoomin = false; // 是否允许放大图像
        public bool zoomout = false; // 是否允许缩小图像
        public int width; // 目标宽度
        public int height; // 目标高度
        public bool free = false; // 当为false的时候，保持图片的比例不变。为true时，则会使宽高等于项目。
        private int threadCount;

        private ThreadTool<AutoResizeItem> Files { get; set; }
        private DirectoryInfo dirInfo;
        private int changedCount = 0;
        private int skipCount = 0;
        private int errorCount = 0;

        public AutoResize(ArgReader arg, IExecutorOwner form, string fpath) : base(arg, form, fpath) {
            isOverride = arg.IsContain("-override");
            width = arg.GetInteger("-width");
            height = arg.GetInteger("-height");
            zoomin = arg.IsContain("-zoomin");
            zoomout = arg.IsContain("-zoomout");
            free = arg.IsContain("-free");
            threadCount = arg.GetInteger("-thread", 1);
        }

        public override void Execute() {
            base.Execute();
            var fs = new List<FileInfo>();
            dirInfo = new DirectoryInfo(FilePath);
            GetAllFiles(dirInfo, fs, Kit.IMG_EXTS);

            Files = new ThreadTool<AutoResizeItem>(threadCount, SetStatus);
            foreach (var i in fs) {
                Files.Add(new AutoResizeItem(this, i));
            }

            Thread t = new Thread(OnProcess);
            t.Start();
        }

        private void OnProcess() {

            changedCount = 0;
            skipCount = 0;
            errorCount = 0;

            Files.Start();

            Flush($"调整完成，总文件：{Files.Items.Count}, 处理:{changedCount}, 跳过:{skipCount}, 出错:{errorCount}");

            End();
        }

        public string GetStatus(string current) {
            return $"进行中({Files.GetComplete()}/{Files.Items.Count}), 线程({Files.GetRuuning()}), 处理/跳过({changedCount}/{skipCount}), 当前: {current}";
        }

        private void Process(FileInfo file) {
            ImageResizer resizer = new ImageResizer(file.FullName, zoomin, zoomout, free == false);

            try {
                resizer.Resize(width, height);
            } catch (OutOfMemoryException) {
                errorCount++;
                resizer.Dispose();
                return;
            }
            

            if (!resizer.Changed) {
                skipCount += 1;
                resizer.Dispose();
                return;
            }

            changedCount += 1;

            // 根据是否覆盖，决定文件的处理
            if (isOverride) {
                resizer.Save(file.FullName); // 直接覆盖
            } else {
                // 需要在目录下新建一个目录
                FileInfo newFile = CreateNewFile(file);
                resizer.Save(newFile.FullName);
            }

            resizer.Dispose();
        }


        private FileInfo CreateNewFile(FileInfo file) {
            var newDir = Path.Combine(file.Directory.FullName, RESIZE_DIR);
            if (Directory.Exists(newDir) == false) {
                Directory.CreateDirectory(newDir);
            }
            return new FileInfo(Path.Combine(newDir, file.Name));
        }

    }
}
